﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 委托案例2
{
    public delegate void GreetingDelegate(string name);
    class Program
    {
        private static void EnglishGreeting(string name)
        {
            Console.WriteLine("Good Morning, " + name);
        }

        private static void ChineseGreeting(string name)
        {
            Console.WriteLine("早上好, " + name);
        }

        private static void GreetPeople(string name, GreetingDelegate MakeGreeting)
        {
            MakeGreeting(name);
        }

        #region  其他调用方法
        //static void Main(string[] args)
        //{
        //    GreetPeople("Liker", EnglishGreeting);
        //    GreetPeople("李志中", ChineseGreeting);
        //    Console.ReadLine();
        //}
        //我们现在对委托做一个总结：委托是一个类，它定义了方法的类型，使得可以将方法当作另一个方法的参数来进行传递，
        //这种将方法动态地赋给参数的做法，可以避免在程序中大量使用If … Else(Switch)语句，同时使得程序具有更好的可扩展性。


        //而既然委托 GreetingDelegate 和类型 string 的地位一样，都是定义了一种参数类型，那么，我可以这么使用委托
        //static void Main(string[] args)
        //{
        //    GreetingDelegate delegate1, delegate2;
        //    delegate1 = EnglishGreeting;
        //    delegate2 = ChineseGreeting;
        //    GreetPeople("Liker", delegate1);
        //    GreetPeople("李志中", delegate2);
        //    Console.ReadLine();
        //}


        //这里，我想说的是委托不同于 string 的一个特性：
        //可以将多个方法赋给同一个委托，或者叫将多个方法绑定到同一个委托，当调用这个委托的时候，将依次调用其所绑定的方法。在这个例子中，语法如下：

        //static void Main(string[] args)
        //{
        //    GreetingDelegate delegate1;
        //    delegate1 = EnglishGreeting;
        //    delegate1 += ChineseGreeting;
        //    GreetPeople("Liker", delegate1);
        //    Console.ReadLine();
        //}
        #endregion

        //实际上，我们可以也可以绕过GreetPeople 方法，通过委托来直接调用EnglishGreeting 和ChineseGreeting：

        //static void Main(string[] args)
        //{
        //    //GreetingDelegate delegate1;
        //    //delegate1 = EnglishGreeting;
        //    //delegate1 += ChineseGreeting;

        //    //delegate1 = ChineseGreeting;
        //    //delegate1 += EnglishGreeting;

        //    //注意这里，第一次用的“=”，是赋值的语法；第二次，用的是“+=”，是绑定的语法。如果第一次就使用“+=”，
        //    //将出现“使用了未赋值的局部变量”的编译错误。我们也可以使用下面的代码来这样简化这一过程：
        //    GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);
        //    delegate1 += ChineseGreeting;
        //    delegate1("Liker");
        //    Console.ReadLine();
        //}


        //既然给委托可以绑定一个方法，那么也应该有办法取消对方法的绑定，很容易想到，这个语法是“-=”：
        static void Main(string[] args)
        {
            GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);
            delegate1 += ChineseGreeting;
            GreetPeople("Liker", delegate1);
            Console.WriteLine();

            delegate1 -= EnglishGreeting;
            GreetPeople("李志中", delegate1);
            Console.ReadLine();
        }
        //让我们再次对委托作个总结：使用委托可以将多个方法绑定到同一个委托变量，当调用此变量时(这里用“调用”这个词，是因为此变量代表一个方法)，可以依次调用所有绑定的方法
    }
}
